package org.jeecg.modules.wms.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.oms.entity.ProductSalesOrderDetail;
import org.jeecg.modules.oms.service.IProductSalesOrderDetailService;
import org.jeecg.modules.system.util.SecurityUtil;
import org.jeecg.modules.wms.entity.FinishedGoodsInventory;
import org.jeecg.modules.wms.entity.FinishedGoodsOutbound;
import org.jeecg.modules.wms.entity.FinishedGoodsOutboundDetail;
import org.jeecg.modules.wms.entity.WmsInventory;
import org.jeecg.modules.wms.service.IFinishedGoodsInventoryService;
import org.jeecg.modules.wms.service.IFinishedGoodsOutboundDetailService;
import org.jeecg.modules.wms.service.IFinishedGoodsOutboundService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 成品出库单Controller
 */
@Api(tags = "成品出库管理")
@RestController
@RequestMapping("/wms/finished-goods/outbound")
@Slf4j
public class FinishedGoodsOutboundController extends JeecgController<FinishedGoodsOutbound, IFinishedGoodsOutboundService> {

    @Autowired
    private IFinishedGoodsOutboundService outboundService;
    
    @Autowired
    private IFinishedGoodsOutboundDetailService detailService;

    @Autowired
    private IFinishedGoodsInventoryService inventoryService;

    /**
     * 分页查询出库单列表
     */
    @ApiOperation(value = "分页查询出库单列表", notes = "分页查询出库单列表")
    @GetMapping("/list")
    public Result<IPage<FinishedGoodsOutbound>> queryPageList(FinishedGoodsOutbound outbound,
                                                              @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                              @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                              HttpServletRequest req) {
        Page<FinishedGoodsOutbound> page = new Page<>(pageNo, pageSize);
        IPage<FinishedGoodsOutbound> pageList = outboundService.queryOutboundList(page, outbound);
        return Result.OK(pageList);
    }

    /**
     * 获取出库单详情
     */
    @ApiOperation(value = "获取出库单详情", notes = "获取出库单详情")
    @GetMapping("/detail/{id}")
    public Result<FinishedGoodsOutbound> getDetail(@PathVariable("id") String id) {
        FinishedGoodsOutbound outbound = outboundService.getById(id);
        if (outbound == null) {
            return Result.error("出库单不存在");
        }
        return Result.OK(outbound);
    }

    /**
     * 新增出库单
     */
    @ApiOperation(value = "新增出库单", notes = "新增出库单")
    @PostMapping("/add")
    public Result<String> add(@Valid @RequestBody FinishedGoodsOutbound outbound) {
        try {
            // 调用Service层方法处理出库单创建，包括明细数据
            String outboundId = outboundService.createOutboundWithDetails(outbound);
            return Result.OK("添加成功！", outboundId);
        } catch (Exception e) {
            log.error("新增出库单失败", e);
            return Result.error("新增失败：" + e.getMessage());
        }
    }

    private LoginUser getCurrentUser() {
        return (LoginUser) SecurityUtils.getSubject().getPrincipal();
    }

    /**
     * 编辑出库单
     */
    @ApiOperation(value = "编辑出库单", notes = "编辑出库单")
    @PutMapping("/edit")
    public Result<String> edit(@Valid @RequestBody FinishedGoodsOutbound outbound) {
        try {
            FinishedGoodsOutbound existOutbound = outboundService.getById(outbound.getId());
            if (existOutbound == null) {
                return Result.error("出库单不存在");
            }
            
            if (existOutbound.getStatus() != 0) {
                return Result.error("只有待审核状态的出库单才能编辑");
            }
            
            outboundService.updateById(outbound);
            return Result.OK("编辑成功!");
        } catch (Exception e) {
            log.error("编辑出库单失败", e);
            return Result.error("编辑失败：" + e.getMessage());
        }
    }

    /**
     * 删除出库单
     */
    @ApiOperation(value = "删除出库单", notes = "删除出库单")
    @DeleteMapping("/delete")
    public Result<String> delete(@RequestParam(name = "id") String id) {
        try {
            return outboundService.deleteById(id);
        } catch (Exception e) {
            log.error("删除出库单失败", e);
            return Result.error("删除失败：" + e.getMessage());
        }
    }

    /**
     * 提交审核
     */
    @ApiOperation(value = "提交审核", notes = "提交审核")
    @PostMapping("/submit/{id}")
    public Result<String> submitForAudit(@PathVariable("id") String id) {
        try {
            boolean result = outboundService.submitForAudit(id, getCurrentUser().getId());
            if (result) {
                return Result.OK("提交审核成功!");
            } else {
                return Result.error("提交审核失败");
            }
        } catch (Exception e) {
            log.error("提交审核失败", e);
            return Result.error("提交审核失败：" + e.getMessage());
        }
    }

    /**
     * 审核出库单
     */
    @ApiOperation(value = "审核出库单", notes = "审核出库单")
    @PostMapping("/audit/{id}")
    public Result<String> audit(@PathVariable("id") String id,
                                @RequestParam("auditResult") Integer auditResult,
                                @RequestParam("auditRemark") String auditRemark) {
        try {
            boolean result = outboundService.auditOutbound(id, auditResult, auditRemark, 
                getCurrentUser().getId(), getCurrentUser().getRealname());
            if (result) {
                String resultText = auditResult == 1 ? "审核通过" : "审核驳回";
                return Result.OK(resultText + "成功!");
            } else {
                return Result.error("审核失败");
            }
        } catch (Exception e) {
            log.error("审核出库单失败", e);
            return Result.error("审核失败：" + e.getMessage());
        }
    }

    /**
     * 取消出库单
     */
    @ApiOperation(value = "取消出库单", notes = "取消出库单")
    @PostMapping("/cancel/{id}")
    public Result<String> cancel(@PathVariable("id") String id,
                                 @RequestParam("reason") String reason) {
        try {
            boolean result = outboundService.cancelOutbound(id, reason, 
                getCurrentUser().getId(), getCurrentUser().getRealname());
            if (result) {
                return Result.OK("取消出库单成功!");
            } else {
                return Result.error("取消出库单失败");
            }
        } catch (Exception e) {
            log.error("取消出库单失败", e);
            return Result.error("取消出库单失败：" + e.getMessage());
        }
    }
    @Autowired
    private IProductSalesOrderDetailService orderDetailService;

    /**
     * 获取出库单明细
     */
    @ApiOperation(value = "获取出库单明细", notes = "获取出库单明细（包含库存信息）")
    @GetMapping("/detail/list/{outboundId}")
    public Result<List<ProductSalesOrderDetail>> getDetailList(@PathVariable("outboundId") String outboundId) {
        try {
                List<Object> orderDetailIdList = detailService.listObjs(new LambdaQueryWrapper<FinishedGoodsOutboundDetail>()
                        .select(FinishedGoodsOutboundDetail::getOrderDetailId)
                        .eq(FinishedGoodsOutboundDetail::getOutboundId, outboundId));
                //根据库存id返回库存数据
            List<ProductSalesOrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<ProductSalesOrderDetail>()
                    .in(ProductSalesOrderDetail::getId, orderDetailIdList));
            return Result.OK(orderDetailList);
        } catch (Exception e) {
            log.error("获取出库单明细失败，出库单ID: {}, 错误信息: {}", outboundId, e.getMessage(), e);
            return Result.error("获取出库单明细失败: " + e.getMessage());
        }
    }


    /**
     * 获取出库单明细
     */
    @ApiOperation(value = "获取出库单明细", notes = "获取出库单明细（包含库存信息）")
    @GetMapping("/detail/outbountList/{outboundId}")
    public Result<List<FinishedGoodsInventory>> getOutboundDetailList(@PathVariable("outboundId") String outboundId) {
        try {
            List<Object> inventoryIdList = detailService.listObjs(new LambdaQueryWrapper<FinishedGoodsOutboundDetail>()
                    .select(FinishedGoodsOutboundDetail::getInventoryId)
                    .eq(FinishedGoodsOutboundDetail::getOutboundId, outboundId));
            //根据库存id返回库存数据
            List<FinishedGoodsInventory> orderDetailList = inventoryService.list(new LambdaQueryWrapper<FinishedGoodsInventory>()
                    .in(FinishedGoodsInventory::getId, inventoryIdList));
            return Result.OK(orderDetailList);
        } catch (Exception e) {
            log.error("获取出库单明细失败，出库单ID: {}, 错误信息: {}", outboundId, e.getMessage(), e);
            return Result.error("获取出库单明细失败: " + e.getMessage());
        }
    }

    /**
     * 一键出库
     */
    @ApiOperation(value = "一键出库", notes = "一键出库")
    @PostMapping("/one-click-outbound/{id}")
    public Result<String> oneClickOutbound(@PathVariable("id") String id) {
        try {
            boolean result = outboundService.oneClickOutbound(id, 
                getCurrentUser().getId(), getCurrentUser().getRealname());
            
            if (result) {
                return Result.OK("一键出库成功!");
            } else {
                return Result.error("一键出库失败");
            }
        } catch (Exception e) {
            log.error("一键出库失败", e);
            return Result.error("一键出库失败：" + e.getMessage());
        }
    }


    /**
     * 根据客户查询出库单
     */
    @ApiOperation(value = "根据客户查询出库单", notes = "根据客户查询出库单")
    @GetMapping("/by-customer/{customerId}")
    public Result<List<FinishedGoodsOutbound>> getByCustomer(@PathVariable("customerId") String customerId) {
        List<FinishedGoodsOutbound> outboundList = outboundService.queryByCustomerId(customerId);
        return Result.OK(outboundList);
    }

    /**
     * 根据状态统计出库单数量
     */
    @ApiOperation(value = "根据状态统计出库单数量", notes = "根据状态统计出库单数量")
    @GetMapping("/count-by-status/{status}")
    public Result<Long> countByStatus(@PathVariable("status") Integer status) {
        Long count = outboundService.countByStatus(status);
        return Result.OK(count);
    }

    /**
     * 分页查询出库单列表（移动端）
     */
    @ApiOperation(value = "分页查询出库单列表（移动端）", notes = "分页查询出库单列表（移动端）")
    @GetMapping("/mobile/list")
    public Result<IPage<FinishedGoodsOutbound>> queryMobilePageList(
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize,
            @RequestParam(name = "outboundStatus", required = false) Integer outboundStatus,
            @RequestParam(name = "outboundNo", required = false) String outboundNo,
            @RequestParam(name = "customerName", required = false) String customerName,
            HttpServletRequest req) {
        
        Page<FinishedGoodsOutbound> page = new Page<>(pageNo, pageSize);
        FinishedGoodsOutbound queryParam = new FinishedGoodsOutbound();
        
        if (outboundStatus != null) {
            queryParam.setStatus(outboundStatus);
        }
        if (outboundNo != null && !outboundNo.trim().isEmpty()) {
            queryParam.setOutboundNo(outboundNo.trim());
        }
        if (customerName != null && !customerName.trim().isEmpty()) {
            queryParam.setCustomerName(customerName.trim());
        }
        
        IPage<FinishedGoodsOutbound> pageList = outboundService.queryOutboundList(page, queryParam);
        return Result.OK(pageList);
    }
}
